package com.leyou.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.auth.utils.UserContext;
import com.leyou.dto.AddressDTO;
import com.leyou.dto.OrderFormDto;
import com.leyou.dto.SkuDTO;
import com.leyou.dto.Order;
import com.leyou.entity.OrderDetail;
import com.leyou.entity.OrderLogistics;
import com.leyou.entity.OrderStatus;
import com.leyou.item.client.ItemClient;
import com.leyou.mapper.OrderMapper;
import com.leyou.myException.LyException;
import com.leyou.service.CartService;
import com.leyou.service.OrderDetailService;
import com.leyou.service.OrderLogisticsService;
import com.leyou.service.OrderService;
import com.leyou.user.client.UserClient;
import feign.FeignException;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    @Autowired
    private ItemClient itemClient;  //商品微服务远程调用接口
    @Autowired
    private UserClient userClient;  //用户微服务远程调用接口
    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private OrderLogisticsService orderLogisticsService;
    @Autowired
    private CartService cartService;
    /**
     * 提交订单，返回订单id
     * @param orderFormDto
     * @return
     */
    @Override
//    @GlobalTransactional
    @Transactional
    public Long submitOrder(OrderFormDto orderFormDto) {
        //1.存储order订单数据
        Order order = new Order();
        order.setUserId(UserContext.getUser().getId());  //用户id
        //根据skuId获得单个商品的金额乘数量求得商品的总金额
        Map<Long, Integer> carts = orderFormDto.getCarts();
        Set<Long> SkuIdSet= carts.keySet();
        List<Long> skuIds = new ArrayList<>(SkuIdSet);
        List<SkuDTO> skuDTOList = itemClient.querySkuByIds(skuIds);
        Long total=0L;
        for (SkuDTO skuDTO : skuDTOList) {
            //判断是否下架
            if (!skuDTO.getSaleable()){
                throw new LyException(400,"该商品已下架");
            }
            //遍历求出对应商品的总价，然后相加
            Integer num = carts.get(skuDTO.getId());
            total+=num*skuDTO.getPrice();
        }
        order.setTotalFee(total);  //商品金额
        order.setStatus(OrderStatus.INIT.getValue());  //订单状态
        order.setPostFee(0L);  //邮费,包邮
        order.setPayTime(new Date()); //付款时间
        order.setPaymentType(orderFormDto.getPaymentType()); //付款方式
        order.setActualFee(total+order.getPostFee());  //实付金额
        //存入数据库
        boolean save = save(order);
        if (!save){
            throw new LyException(500,"订单创建失败");
        }
        //2.存储OrderDetail订单详情数据
        ArrayList<OrderDetail> detailList = new ArrayList<>();
        for (SkuDTO skuDTO : skuDTOList) {
            OrderDetail detail = new OrderDetail();
            detail.setTitle(skuDTO.getTitle());  //标题
            detail.setSpec(skuDTO.getSpecialSpec());  //规格参数
            detail.setSkuId(skuDTO.getId());  //skuId
            detail.setPrice(skuDTO.getPrice());  //价格
            detail.setOrderId(order.getOrderId());    //订单id
            detail.setNum(carts.get(skuDTO.getId()));    //数量
            detail.setImage(skuDTO.getImages());  //图片
            detailList.add(detail);
        }
        //把订单详情批量存入数据库
        boolean saveDetailList = orderDetailService.saveBatch(detailList);
        if (!saveDetailList){
            throw new LyException(500,"订单创建失败");
        }
        //3.存储OrderLogistics订单物流数据
        AddressDTO addressDTO = userClient.getMyAddressById(orderFormDto.getAddressId());
        OrderLogistics orderLogistics = addressDTO.toEntity(OrderLogistics.class);
        orderLogistics.setOrderId(order.getOrderId());
        boolean saveOrderLogistics = orderLogisticsService.save(orderLogistics);
        if (!saveOrderLogistics){
            throw new LyException(500,"订单创建失败");
        }
        //4.删除库存，添加销量
        try {
            System.out.println(carts);
            itemClient.deductStock(carts);
        } catch (FeignException e) {
            throw new LyException(e.status(),e.contentUTF8());
        }
        System.out.println(order.getOrderId());
        //下单完成要删除购物车中的数据
        for (SkuDTO skuDTO : skuDTOList) {
            cartService.deleteCartBySkuId(skuDTO.getId());
        }
        return order.getOrderId();
    }
}